package com.kinyx.framework.bean;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.kinyx.framework.annotation.assist.CanNull;
import com.kinyx.framework.annotation.assist.Note;
import com.kinyx.framework.annotation.assist.ReturnNotNull;
import com.kinyx.framework.annotation.assist.ReturnNull;
import com.kinyx.framework.annotation.assist.Tester;

/**
 * 双键集合
 * @param <K1> 键1泛型
 * @param <K2> 键2泛型
 * @param <V> 值泛型
 */
@Tester("com.kinyx.framework.bean.DKHashMap_Tester_")
public final class DKHashMap<K1, K2, V> {

	// ===================================================== field ===================================================== //
	/** 内置集合对象 */
	private final Map<K1, Map<K2, V>> map = new HashMap<>();

	// ===================================================== method ===================================================== //
	/**
	 * 清空数据
	 * @return 本对象
	 */
	@ReturnNotNull
	@Note("return this;")
	public DKHashMap<K1, K2, V> clear() {
		this.map.clear();
		return this;
	}

	/**
	 * 增加元素
	 * @param key1 键1
	 * @param key2 键2
	 * @param value 值
	 * @return 本对象
	 */
	@ReturnNotNull
	@Note("return this;")
	public DKHashMap<K1, K2, V> put(@CanNull final K1 key1, @CanNull final K2 key2, @CanNull final V value) {
		Map<K2, V> map = this.map.get(key1);
		if (map == null) {
			map = new HashMap<>();
			this.map.put(key1, map);
		}
		map.put(key2, value);
		return this;
	}

	/**
	 * 取元素
	 * @param key1 键1
	 * @param key2 键2
	 * @return 值
	 */
	@ReturnNull("未存储过该值")
	@ReturnNull("存储的值为null")
	public V get(@CanNull final K1 key1, @CanNull final K2 key2) {
		final Map<K2, V> map = this.map.get(key1);
		if (map == null) { return null; }
		return map.get(key2);
	}

	/**
	 * 判断是否为空
	 * @return true：存储过值；false：未存储过值；
	 */
	public boolean isEmpty() { return this.map.isEmpty(); }

	/**
	 * 按照键1取值列表
	 * @param key1 键1
	 * @return 值列表
	 */
	public Collection<V> getListByKey1(final String key1) {
		final Map<K2, V> map = this.map.get(key1);
		return map == null ? Collections.emptyList() : map.values();
	}

	/**
	 * 按照键2取值列表
	 * @param key2 键2
	 * @return 值列表
	 */
	public Collection<V> getListByKey2(final String key2) {
		if (this.map.isEmpty()) { return Collections.emptyList(); }
		final Collection<V> results = new ArrayList<>();
		this.map.forEach((k1, maps) -> {
			final V v = maps.get(key2);
			if (v != null) { results.add(v); }
		});
		return results;
	}

}
